home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / foomatic-ppdfile < prev    next >
Text File  |  2009-09-18  |  9KB  |  301 lines

  1. #!/usr/bin/perl
  2. # -*- perl -*-
  3.  
  4. # Foomatic PPD file generator for manual PPD generation (via "-p",
  5. # "-d", "-A", and "-P" command line options) or for automatic
  6. # on-the-fly PPD generation by CUPS 1.2 or newer (via "cat" and "list"
  7. # command line options).
  8.  
  9. use Foomatic::Defaults;
  10. use Foomatic::DB;
  11. use Getopt::Std;
  12. use Data::Dumper;
  13. #use strict;
  14.  
  15. my $debug = 0;
  16.  
  17. # Use program name as the first part of the PPD URI for CUPS (should be 
  18. # "foomatic").
  19. $0 =~ m!/([^/]+)\s*$!;
  20. my $progname = ($1 || $0);
  21.  
  22. # Default settings for listing PPDs by cups-driverd
  23.  
  24. # List only the PPD file with the reconmmended driver for each printer
  25. # and do not show "(recommended)" in the CUPS web interface. This mode
  26. # makes CUPS setup with the web interface very easy for beginners.
  27. # This can be set by "OnlyRecommended Yes" or "OnlyRecommended No" in
  28. # /etc/cups/foomatic.conf
  29. my $onlyrecommended = 0;
  30. # The Foomatic database does not only generate PPD files from Foomatic
  31. # XML data but also of ready-made PPDs mainly from printer manufacturers
  32. # for their PostScript printers. As these PPDs are often also linked to
  33. # the directories in which CUPS links directly to PPD files, duplicate
  34. # listing of these PPDs by CUPS would result. Therefore we suppress
  35. # listing the ready-made PPDs. This behaviour can be changed by using
  36. # "ListReadyMadePPDs Yes" or "ListReadyMadePPDs No" in
  37. # /etc/cups/foomatic.conf
  38. my $listreadymadeppds = 0;
  39. help() if !@ARGV;
  40. #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w);
  41. getopts("AP:d:p:hwt:");
  42. help() if $opt_h;
  43. my $drv = $opt_d;
  44. my $poid   = $opt_p;
  45. my $showall   = $opt_A;
  46. my $showmatch   = $opt_P;
  47. help() if ($#ARGV > 1) && !($poid);
  48.  
  49. if ($ARGV[0] =~ /^list$/i) {
  50.     # List all available PPD files (format for cups-driverd)
  51.     cupslistppds();
  52. } elsif ($ARGV[0] =~ /^cat$/i) {
  53.     # Generate and return the selected PPD file (cups-driverd command line)
  54.     generateppd($ARGV[1]);
  55. } elsif ($showall or $showmatch) {
  56.     # List all PPD files or files matching regexp (manual operation)
  57.     foomaticlistppds($showmatch);
  58. } elsif ($poid) {
  59.     # Generate and return the selected PPD file (manual operation)
  60.     generateppd($poid, $drv);
  61. } else {
  62.     help();
  63. }
  64.  
  65. exit(0);
  66.  
  67. sub cupslistppds {
  68.  
  69.     # Read configuration in /etc/cups/foomatic.conf
  70.     my $conffilename;
  71.     if (my $cupsserverroot = $ENV{CUPS_SERVERROOT}) {
  72.         $conffilename = "$cupsserverroot/foomatic.conf";
  73.     } else {
  74.         $conffilename = "/etc/cups/foomatic.conf";
  75.     }
  76.     if (-r $conffilename and
  77.     open CONF, "< $conffilename") {
  78.     while (my $line = <CONF>) {
  79.         chomp $line;
  80.         if ($line =~
  81.         /^\s*OnlyRecommended\s+(Yes|On|True|1)\s*$/i) {
  82.         $onlyrecommended = 1;
  83.         } elsif ($line =~
  84.              /^\s*OnlyRecommended\s+(No|Off|False|0)\s*$/i) {
  85.         $onlyrecommended = 0;
  86.         }
  87.         if ($line =~
  88.         /^\s*ListReadyMadePPDs\s+(Yes|On|True|1)\s*$/i) {
  89.         $listreadymadeppds = 1;
  90.         } elsif ($line =~
  91.              /^\s*ListReadyMadePPDs\s+(No|Off|False|0)\s*$/i) {
  92.         $listreadymadeppds = 0;
  93.         }
  94.     }
  95.     close CONF;
  96.     }
  97.  
  98.     my $db = Foomatic::DB->new();
  99.     $db->get_overview(1, 1 + listreadymadeppds);
  100.  
  101.     for my $printer (@{$db->{'overview'}}) {
  102.     my $poid = $printer->{'id'};
  103.     my $make = $printer->{'make'};
  104.     my $model = $printer->{'model'};
  105.     my $recdriver = $printer->{'driver'};
  106.     my @drivers = @{$printer->{'drivers'}};
  107.     my $id = $printer->{'ieee'};
  108.  
  109.     # No drivers => No PPDs
  110.     next if $#drivers < 0;
  111.  
  112.     # Put the reconmmended driver to the beginning of list, as CUPS
  113.     # probably will take the first PPD which matches the printer model
  114.     my @sorteddrivers;
  115.     if (Foomatic::DB::member($recdriver, @drivers)) {
  116.         # Valid entry for the recommended driver
  117.         push(@sorteddrivers, $recdriver);
  118.         if (!$onlyrecommended) {
  119.         foreach my $driver (@drivers) {
  120.             push(@sorteddrivers, $driver) if $driver ne $recdriver;
  121.         }
  122.         }
  123.     } else {
  124.         # Invalid entry for the recommended driver
  125.         next if $onlyrecommended;
  126.         undef $recdriver;
  127.         @sorteddrivers = @drivers;
  128.     }
  129.  
  130.     # Go through all the drivers and list the PPD entries
  131.     foreach my $driver (@sorteddrivers) {
  132.         # Get PPD header data from the PPD file generator
  133.         my ($ieee1284,$pnpmake,$pnpmodel,$filename,$longname,
  134.         $drivername,$nickname,$modelname) =
  135.             Foomatic::DB::getppdheaderdata($printer, $driver, 
  136.                            ($onlyrecommended ? '' :
  137.                             $printer->{'driver'}));
  138.         print "\"$progname:$printer->{'id'}-$driver.ppd\" en \"$make\" \"$nickname\" \"$ieee1284\"\n";
  139.     }
  140.     }
  141. }
  142.  
  143. sub foomaticlistppds {
  144.  
  145.     my ($match) = @_;
  146.  
  147.     my $db = Foomatic::DB->new();
  148.     $db->get_overview();
  149.     my @drivers = $db->get_driverlist();
  150.  
  151.     for my $printer (@{$db->{'overview'}}) {
  152.     my $pr = $printer->{'make'};
  153.     my $model = $printer->{'model'};
  154.     my $name = "$pr $model";
  155.     my $driver = ($printer->{'driver'} || "No Default Driver");
  156.     my $dlist = "";
  157.     my $dcount = 0;
  158.     if( $printer->{'drivers'} ){
  159.         $dcount = @{$printer->{'drivers'}};
  160.         for my $d (@{$printer->{'drivers'}}) {
  161.         $dlist .= "$d ";
  162.         }
  163.     }
  164.     if (not $match or "$name" =~ m{$match}o) {
  165.         print "$name Id='$printer->{'id'}' Driver='$driver'";
  166.         if ($dcount > 1){
  167.         print " CompatibleDrivers='$dlist'";
  168.         }
  169.         print "\n";
  170.     }
  171.     }
  172. }
  173.  
  174. sub generateppd {
  175.  
  176.     my ($ppduri, $driver) = @_;
  177.     my $poid;
  178.  
  179.     my $db = Foomatic::DB->new();
  180.     $db->get_overview();
  181.     my $printer;
  182.     my @drivers = $db->get_driverlist();
  183.  
  184.     if ($ppduri =~ /^$progname:(.*)\.ppd$/) {
  185.     # cups-driverd operation
  186.     # We try to split between printer name and driver name at all
  187.     # dashes in the PPD file name, as some drivers (ex. Gutenprint)
  188.     # have dashes in their names.
  189.     my $ppdname = $1;
  190.     my @poidcomponents = split(/-/, $ppdname);
  191.     my @drivercomponents = ();
  192.     while ($#poidcomponents > 1) {
  193.         unshift(@drivercomponents, pop(@poidcomponents));
  194.         $driver = join('-', @drivercomponents);
  195.         next if !Foomatic::DB::member($driver, @drivers);
  196.         $poid = join('-', @poidcomponents);
  197.         last;
  198.     }
  199.     die "ERROR: Could not determine driver name for $ppdname.ppd!\n"
  200.         if( !$poid );
  201.     } else {
  202.     # manual operation
  203.     $poid = $ppduri;
  204.     }
  205.  
  206.     # If the user supplies an old numerical printer ID, translate it to
  207.     # a new clear-text ID
  208.     $poid = Foomatic::DB::translate_printer_id($poid);
  209.  
  210.     my $lcname = lc( $poid );
  211.     my $pentry;
  212.     for $printer (@{$db->{'overview'}}) {
  213.     my $name = lc( $printer->{'id'} );
  214.     print STDERR "DEBUG2: $progname: compare '$lcname' to '$name'\n" if $debug;
  215.     if( $name eq $lcname ){
  216.         $pentry = $printer;
  217.         last;
  218.     }
  219.     }
  220.  
  221.     die "ERROR: Printer '$poid' not found!\n" if( not defined $pentry );
  222.     print STDERR "DEBUG: $progname: Found $pentry->{id}\nDEBUG2: $progname: " .
  223.     join ("\nDEBUG2: $progname: ", split(/\n/, Dumper($pentry))) .
  224.     "\n" if $debug;
  225.     
  226.     if (!$driver || ($driver =~ /(default|recommended)/i)) {
  227.     $driver = $pentry->{'driver'};
  228.     if( not defined( $driver ) ){
  229.         die "ERROR: $progname: Printer '$poid' does not have default driver!\n";
  230.     }
  231.     }
  232.     
  233.     my $found = 0;
  234.     for my $d (@{$pentry->{'drivers'}}) {
  235.     last if ($found = ($driver eq $d));
  236.     }
  237.     if ( not $found ) {
  238.     warn "ERROR: $progname: Printer '$poid' and driver '$driver' are not compatible\n";
  239.     }
  240.     $found = 0;
  241.     for my $d (@drivers) {
  242.     last if ($found = ($driver eq $d));
  243.     }
  244.     if ( not $found ) {
  245.     die "ERROR: $progname: Driver '$driver' not in database!\n";
  246.     }
  247.  
  248.     # Get all the data about this driver/printer pair
  249.     my $possible = $db->getdat($driver, $poid);
  250.     # Stop if the printer is not supported by the given driver
  251.     die "ERROR: $progname: That printer and driver combination is not possible.\n"
  252.     if (!$possible);
  253.     # Stop if the driver entry has an empty command line prototype or if there 
  254.     # is no custom PPD file
  255.     die "ERROR: $progname: There is neither a custom PPD file nor the driver database entry contains sufficient data to build a PPD file.\n"
  256.     if (!$db->{'dat'}{'cmd'}) && (!$db->{'dat'}{'ppdfile'});
  257.     
  258.     my @data;
  259.  
  260.     @data = $db->getppd($opt_w);
  261.     die "ERROR: $progname: No PPD file for printer '$poid' and driver '$driver'!\n"
  262.     if not @data;
  263.  
  264.     print @data;
  265.  
  266. }
  267.  
  268. sub help {
  269.     print <<HELP;
  270.  
  271. $progname -A
  272. $progname -P <regexpr>
  273. $progname -p <printerid> [-d <driver>] [-w]
  274. $progname list
  275. $progname cat <CUPS PPD URI> [-w]
  276. $progname -h
  277.  
  278.  -A             : show all Printer ID's and compatible drivers
  279.  -P <regexpr>   : show all Printer ID's whose names and model
  280.                   matched by the RE.  For example:
  281.                    -P HP will match all names with HP in them
  282.  -p <printerid> : Printer ID
  283.  -d <driver>    : Driver name
  284.                   If the driver is not specified then the default driver 
  285.                   for the <printerid> is used.
  286.  list           : List all possible PPDs in the format needed by the
  287.                   cups-driverd
  288.  cat <CUPS PPD URI> : Generate PPD file appropriate to the <CUPS PPD URI>.
  289.                   Available CUPS PPD URIs are listed by 
  290.                   "$progname list".
  291.  -w             : Generate PPD which is compatible with the CUPS PostScript
  292.                   driver for Windows (GUI strings are limited to 39 
  293.                   characters).
  294.  -h             : show help information
  295.  
  296.  
  297. HELP
  298.     exit 1;
  299.  
  300. }
  301.